package com.fulu.game.bi.service.impl.channel;

import cn.hutool.core.collection.CollectionUtil;
import com.fulu.game.bi.common.exception.BizException;
import com.fulu.game.bi.entity.enums.GroupRelTableEnum;
import com.fulu.game.bi.entity.po.auth.BiUser;
import com.fulu.game.bi.entity.po.channel.GroupRel;
import com.fulu.game.bi.entity.po.channel.RegistSource;
import com.fulu.game.bi.entity.po.channel.RegistSourceGroup;
import com.fulu.game.bi.entity.vo.channel.source.RegisterSourceGroupDisplayVO;
import com.fulu.game.bi.entity.vo.channel.source.RegisterSourceGroupQueryVO;
import com.fulu.game.bi.entity.vo.channel.source.RegisterSourceGroupSaveVO;
import com.fulu.game.bi.enums.CommonlyOrderEnums;
import com.fulu.game.bi.mysql.bi.channel.GroupRelDao;
import com.fulu.game.bi.mysql.bi.channel.RegisterSourceGroupDao;
import com.fulu.game.bi.mysql.playadmin.channel.RegistSourceDao;
import com.fulu.game.bi.redis.service.auth.BiUserService;
import com.fulu.game.bi.redis.service.channel.RegisterSourceGroupService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RegisterSourceGroupServiceImpl implements RegisterSourceGroupService {

    @Autowired
    private BiUserService biUserService;
    @Autowired
    private RegisterSourceGroupDao registerSourceGroupDao;
    @Autowired
    private RegistSourceDao registSourceDao;
    @Autowired
    private GroupRelDao groupRelDao;

    @Override
    public RegistSourceGroup save(RegisterSourceGroupSaveVO vo) {
        if (Objects.isNull(vo.getId())) {
            return createNewGroup(vo);
        }

        return updateExistGroup(vo);
    }

    public void addRel(List<GroupRel> list) {
        groupRelDao.insert(list, GroupRelTableEnum.REGISTER_SOURCE.getName());
    }

    private RegistSourceGroup updateExistGroup(RegisterSourceGroupSaveVO vo) {
        RegistSourceGroup existGroup = registerSourceGroupDao.findByName(vo.getGroupName());

        if (Objects.nonNull(existGroup) && !Objects.equals(existGroup.getId(), vo.getId())) {
            throw new BizException("分组名已存在");
        }
        RegistSourceGroup group = new RegistSourceGroup();
        BeanUtils.copyProperties(vo, group);
        Date now = new Date();
        BiUser currentUser = biUserService.getCurrentUser();

        group.setName(vo.getGroupName());
        group.setUpdateTime(now);
        group.setUpdateUser(currentUser.getId());

        registerSourceGroupDao.updateSelective(group);

        return group;
    }

    private RegistSourceGroup createNewGroup(RegisterSourceGroupSaveVO vo) {
        RegistSourceGroup existGroup = registerSourceGroupDao.findByName(vo.getGroupName());

        if (Objects.nonNull(existGroup)) {
            throw new BizException("分组名已存在");
        }


        RegistSourceGroup group = new RegistSourceGroup();
        BeanUtils.copyProperties(vo, group);
        Date now = new Date();
        BiUser currentUser = biUserService.getCurrentUser();

        group.setName(vo.getGroupName());
        group.setCreateTime(now);
        group.setUpdateTime(now);
        group.setCreateUser(currentUser.getId());
        group.setUpdateUser(currentUser.getId());

        registerSourceGroupDao.insert(group);

        return group;
    }

    @Override
    public PageInfo<RegisterSourceGroupDisplayVO> list(RegisterSourceGroupQueryVO vo) {
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize(), CommonlyOrderEnums.UPDATE_DESC.getValue());

        List<RegistSourceGroup> list = registerSourceGroupDao.list(vo);
        PageInfo pageInfo = new PageInfo(list);
        List<RegisterSourceGroupDisplayVO> result = list.stream()
                .map(this::compute)
                .collect(Collectors.toList());
        pageInfo.setList(result);
        return pageInfo;
    }

    @Override
    @Transactional
    public Boolean delete(Integer id) {
        Boolean deleted = false;
        List<Integer> ids = registerSourceGroupDao.listItem(id);
        if (CollectionUtil.isEmpty(ids)) {
            deleted = registerSourceGroupDao.deleteById(id) > 0;
        } else {
            List<RegistSource> registSources = registSourceDao.findByIds(ids);
            if (CollectionUtil.isEmpty(registSources)) {
                deleted = registerSourceGroupDao.deleteById(id) > 0 && groupRelDao.deleteByGroupId(id, GroupRelTableEnum.REGISTER_SOURCE.getName()) > 0;
            }
        }
        return deleted;
    }

    protected RegisterSourceGroupDisplayVO compute(RegistSourceGroup source) {
        RegisterSourceGroupDisplayVO target = new RegisterSourceGroupDisplayVO();
        target.setId(source.getId());
        target.setGroupName(source.getName());
        List<Integer> ids = registerSourceGroupDao.listItem(source.getId());
        target.setNum(0);
        target.setItemList(Collections.emptyList());
        if (CollectionUtil.isNotEmpty(ids)) {
            List<RegistSource> registSources = registSourceDao.findByIds(ids);
            target.setNum(registSources.size());
            target.setItemList(registSources);
        }
        target.setAdminId(source.getCreateUser());
        BiUser user = Optional.ofNullable(biUserService.findById(source.getUpdateUser())).orElse(new BiUser());
        target.setAdminName(user.getName());
        target.setCreateTime(source.getCreateTime());
        target.setUpdateTime(source.getUpdateTime());
        target.setRemark(source.getRemark());
        return target;
    }
}
